說到css in js,也就是用js來寫css 就不得不提到style components,被稱之為是React樣式處理的最佳方案!
首先安裝 style components
yarn add styled-components
接著再引入
import styled from "styled-components";
styled後面可以放任何的html tag,定義完畢後就可以當成一般component使用,然後命名的第一個字一定要是大寫,不然會美丁美當。(話說第一次看到這種寫法覺得很不可思議
render(){
const Content = styled.ul`
outline:3px solid olive;
color:#aaa;
`;
return (
<Content className="list">
{
this.state.order.map((item)=>{
return (<li>{item}</li>)
})
}
</Content>
)
}
//styled.button`` 就等同於 style.button(),``可以把它想成是es6的樣板語言,會比較好理解。
然後打開f12開發者工具看一下html結構,可以觀察到會自動生成亂數的class,這是為了不要讓class name重複
我們可以利用三元運算式來根據props的變化改變樣式
render(){
const Content = styled.ul`
outline:3px solid olive;
color:#aaa;
background:${props => (props.favorite ? 'steelblue' :'transparent')};
`;
return (
<Content className="list">
{
this.state.order.map((item)=>{
return (<li>{item}</li>)
})
}
</Content>
)
}
渲染過後的畫面
也可以利用類似scss的巢狀寫法,設定子元素的樣式
const Content = styled.ul`
outline:3px solid olive;
color:#aaa;
background:${props => (props.favorite ? 'steelblue' :'transparent')};
li{
opacity:0.2;
}
`;
這邊還提供了一個類似scss extend的功能,可以繼承現有styled,再撰寫自己獨有的樣式,將Content的樣式傳入Content2的styled(),如此一來Content2也會有Content的樣式
const Content = styled.ul`
outline:3px solid olive;
color:#aaa;
background:${props => (props.favorite ? 'steelblue' :'transparent')};
li{
opacity:0.2;
}
`;
const Content2 = styled(Content)`
box-shadow:10px 10px rgba(255,255,255,.5);
`;
return (
<Content2 favorite={true} className="list">
{
this.state.order.map((item)=>{
return (<li>{item}</li>)
})
}
</Content2>
)
也可以利用attr屬性來傳入其他html屬性
const Email = styled.input.attrs({
type: 'email',
})`
font-size: 20px;
border: 2px solid steelblue;
`;
不過個人還是比較習慣CSS Modules,將js和css分開處理,styled components css in js的做法還需要一點時間習慣。